package com.ums.upos.service;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.OperationCanceledException;
import android.os.RemoteException;
import android.preference.PreferenceManager;
import com.ums.upos.uapi.ServiceResult;
import com.ums.upos.uapi.device.scanner.InnerScanner;
import com.ums.upos.uapi.device.scanner.OnScannedListener;
import com.ums.upos.uapi.device.scanner.ScannerConfig;
import net.sourceforge.zbar.android.CaptureActivity;
import net.sourceforge.zbar.android.PreferencesActivity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import rx.Observable;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.subjects.BehaviorSubject;

/**
 * 扫描服务类
 */
public class ScannerBinder extends InnerScanner.Stub {
    private static final String TAG = "ScannerService";
    private Logger log;
    private Context context;
    private BehaviorSubject<String> subject;
    private final String ACTION_CLOSE_SCANNER = "com.nexgo.zxing.close";
    private final String ACTION_RESULT_SCANNER = "com.nexgo.zxing.result";

    /**
     * 广播接收者，接收来自扫描结果的广播
     */
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {

        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            log.debug("action {}", action);
            if (ACTION_RESULT_SCANNER.equals(action)) {
                subject.onNext(intent.getStringExtra("data"));
                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
                boolean isConttinue = prefs.getBoolean(PreferencesActivity.KEY_BULK_MODE, false);
                if (!isConttinue) {
                    log.debug("收到数据结束描码");
                    subject.onCompleted();
                }
            }
            if (ACTION_CLOSE_SCANNER.equals(action)) {
                subject.onError(new OperationCanceledException());
            }
        }
    };

    ScannerBinder(Context context) {
        this.context = context;
        log = LoggerFactory.getLogger(TAG);
    }

    @Override
    public void initScanner(Bundle bundle) throws RemoteException {
        log.info("call initScanner");
        log.info("call initScanner bundle："+bundle.toString());
        SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
        if (bundle != null) {

            //如果传进来的是0，存true（前置）
            editor.putBoolean(PreferencesActivity.KEY_USED_FRONT_CCD, bundle.getInt(ScannerConfig.COMM_SCANNER_TYPE, 1) == 0);
            //是否连续扫描
            editor.putBoolean(PreferencesActivity.KEY_BULK_MODE, bundle.getBoolean(ScannerConfig.COMM_ISCONTINUOUS_SCAN, false));
            //editor.putBoolean(PreferencesActivity.COMM_FRONT_SHOW, bundle.getBoolean(ScannerConfig.COMM_FRONT_SHOW, true));
            //连续扫描间隔时间
            editor.putString(PreferencesActivity.KEY_BULK_MODE_PERIOD, String.valueOf(bundle.getInt(ScannerConfig.COMM_CONTINUOUS_SCAN_PERIOD, 1000)));
        } else {
            //默认初始化为后摄像头
            editor.putBoolean(PreferencesActivity.KEY_USED_FRONT_CCD, false);
        }
        editor.apply();
    }
    @Override
    public int startScan(final int timeout, final OnScannedListener listener) throws RemoteException {

        log.info("call startScan");
        if (listener == null) return ServiceResult.Param_In_Invalid;
//        int numCameras = Camera.getNumberOfCameras();
        //如果没有摄像头要启用激光一维扫码
        //重复调用
        if (subject != null && subject.hasObservers()) {
            log.debug("上次的扫描未结束");
            listener.onScanResult(ServiceResult.Fail, null);
            return ServiceResult.Fail;
        }
        subject = BehaviorSubject.create();

        Observable<String> observable = subject.asObservable();
        if (timeout > 0) {
            log.debug("timeout :{}", timeout);
            observable = observable.timeout(timeout, TimeUnit.SECONDS);
        }

        observable.doOnSubscribe(new Action0() {
            @Override
            public void call() {
                IntentFilter filter = new IntentFilter();
                filter.addAction(ACTION_RESULT_SCANNER);
                filter.addAction(ACTION_CLOSE_SCANNER);
                context.registerReceiver(mReceiver, filter);
                Intent intent = new Intent();
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.setClass(context, CaptureActivity.class);
                context.startActivity(intent);
            }
        }).doOnError(new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {

                        Intent intent = new Intent();
                        intent.setAction(ACTION_CLOSE_SCANNER);
                        context.sendBroadcast(intent);// 把收到的消息以广播的形式发送出去
                    }
                })
                .finallyDo(new Action0() {
                    @Override
                    public void call() {
                        try {
                            context.unregisterReceiver(mReceiver);
                        } catch (IllegalArgumentException e) {
                            e.printStackTrace();
                        }
                    }
                })
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        log.debug("扫描得到数据 {}", s);
                        byte[] data = s.getBytes();
                        try {
                            listener.onScanResult(ServiceResult.Success, data);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        log.debug("扫描退出");
                        int result;
                        if (throwable instanceof OperationCanceledException) {
                            result = ServiceResult.Scanner_Customer_Exit;
                        } else if (throwable instanceof TimeoutException) {
                            log.error("scan timeout.");
                            result = ServiceResult.TimeOut;
                        } else {
                            result = ServiceResult.Scanner_Other_Error;
                        }
                        try {
                            listener.onScanResult(result, null);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                    }
                });

        return ServiceResult.Success;
    }

    @Override
    public void stopScan() throws RemoteException {
        log.info("call stopScan");
        if (subject != null) {
            subject.onError(new OperationCanceledException());
        }
    }
}
